package com.centriole.service.exuser.service.impl;


import com.centriole.common.entity.*;
import com.centriole.common.utils.CommonUtil;
import com.centriole.common.utils.PaasResult;
import com.centriole.common.utils.TokenUtil;
import com.centriole.service.exuser.dao.ExUserMapper;
import com.centriole.service.exuser.service.ExUserService;
import com.github.pagehelper.PageHelper;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.Arrays;
import java.util.Date;
import java.util.List;

/**
 * 功   能： ExUserService 统一用户管理Service实现类
 * 创建人：陈默晗
 * 时   间：2018年4月11日上午10:11:51
 */
@Service
public class ExUserServiceImpl implements ExUserService {

    @Autowired
    ExUserMapper exUserMapper;

    /**
     * 添加 (对外使用的)用户
     *
     * @param user ExUser对象
     * @return true表示添加成功；false表示添加失败
     */
    @Override
    public boolean addExUser(ExUser user) {
        return exUserMapper.insertExUser(user) > 0;
    }

    /**
     * 根据UserId 逻辑删除(对外使用的)用户
     *
     * @param userId String(32位UUID)
     * @return true表示添加成功；false表示添加失败
     */
    @Override
    public boolean removeExUser(String userId) {
        ExUser exUser = exUserMapper.selectByUserId(userId);
        if (exUser == null) return false;
        exUser.setStatus(2);
        return exUserMapper.update(exUser) > 0;
    }

    /**
     * 修改(对外使用的)用户信息
     *
     * @param user
     * @return true表示添加成功；false表示添加失败
     */
    @Override
    public boolean modifyExUser(ExUser user) {
        return exUserMapper.update(user) > 0;
    }

    /**
     * 查询所有(对外使用的)用户
     *
     * @return
     */
    @Override
    public List<ExUser> listAllExUsers() {
        return exUserMapper.selectAll();
    }

    /**
     * 指定用户Id(32位UUID)来查询用户
     *
     * @param userId String 32位UUID
     * @return ExUser对象
     */
    @Override
    public ExUser findExUserByUserId(String userId) {
        return exUserMapper.selectByUserId(userId);
    }

    /**
     * 指定账号名来查询用户
     *
     * @param accountName 账号名
     * @return ExUser对象
     */
    @Override
    public ExUser findExUserByAccountName(String accountName) {
        return exUserMapper.selectByAccountName(accountName);
    }

    /**
     * 指定 角色id 来查询相关的用户
     *
     * @param roleId String 32位UUID
     * @return List<ExUser>
     */
    @Override
    public List<ExUser> listExUsersByRoleId(String roleId) {
        return exUserMapper.selectByRoleId(roleId);
    }

    /**
     * 指定 角色名 来查询相关的用户
     *
     * @param roleName String  角色名
     * @return List<ExUser>
     */
    @Override
    public List<ExUser> listExUsersByRoleName(String roleName) {
        return exUserMapper.selectByRoleName(roleName);
    }

    /**
     * 指定 权限id 来查询相关的用户
     *
     * @param permissionId String 32位UUID
     * @return List<ExUser>
     */
    @Override
    public List<ExUser> selectByPermissionId(String permissionId) {
        return exUserMapper.selectByPermissionId(permissionId);
    }

    /**
     * 指定 权限名 来查询相关的用户
     *
     * @param permissionName 权限名
     * @return List<ExUser>
     */
    @Override
    public List<ExUser> selectByPermissionName(String permissionName) {
        return exUserMapper.selectByPermissionName(permissionName);
    }

    /**
     * 给指定用户关联角色
     *
     * @param userId  String 32位UUID
     * @param roleIds 至少1个roleIds String 32位UUID
     * @return true表示添加成功；false表示添加失败
     */
    @Override
    public boolean relateUserAndRole(String userId, String... roleIds) {
        if (roleIds == null || roleIds.length == 0) return false;
        Arrays.asList(roleIds).parallelStream().forEach(e -> {
            exUserMapper.relateUserAndRole(userId, e);
        });
        return true;
    }

    /**
     * 给指定角色关联权限
     *
     * @param roleId        String 32位UUID
     * @param permissionIds 至少1个PermissionId String 32位UUID
     * @return true表示添加成功；false表示添加失败
     */
    @Override
    public boolean relateRoleAndPermission(String roleId, String... permissionIds) {
        if (permissionIds == null || permissionIds.length == 0) return false;
        Arrays.asList(permissionIds).parallelStream().forEach(e -> {
            exUserMapper.relateUserAndRole(roleId, e);
        });
        return true;
    }

    /**
     * 关联查询出 (对外使用的)用户信息(包含该用户的基本信息、拥有角色、拥有权限)
     *
     * @return List<ExUser>(包含该用户的基本信息、拥有角色、拥有权限)
     */
    @Override
    public List<ExUser> listRAllExUsers(Page page) {
        if (page != null) {
            PageHelper.startPage(page.getPage(), page.getLimit());
        }
        return exUserMapper.selectRAll();
    }

    /**
     * 关联查询出 所有角色(还包含了所属权限)
     *
     * @return List<ExRole>(包含该角色的基本信息、拥有权限)
     */
    @Override
    public List<ExRole> listRAllRoles() {
        return exUserMapper.selectRAllRoles();
    }

    /**
     * 根据UserId 关联查询出用户(包含该用户的基本信息、拥有角色、拥有权限)
     *
     * @param userId String 32位UUID
     * @return ExUser对象(包含该用户的基本信息 、 拥有角色 、 拥有权限)
     */
    @Override
    public ExUser findRByUserId(String userId) {
        return exUserMapper.selectRByUserId(userId);
    }

    /**
     * 用户注册 或者 用户登录，注册或者登录成功后返回一个token
     *
     * @param exUser exUser对象
     * @return String token
     */
    @Override
    @Transactional
    public PaasResult login(ExUser exUser, String ip) {
        //获取用户的 用户名 和 密码
        String accountName = exUser.getAccountName();
        String password = exUser.getPassword();
        String signature = CommonUtil.getUuid();
        Date lastLogin = new Date();
        String userId = null;

        //数据库已存在该用户，则尝试登录
        ExUser exUserFromDb = null;
        if ((exUserFromDb = exUserMapper.selectByAccountName(accountName)) != null) {
            userId = exUserFromDb.getUserId();
            if (!password.equals(exUser.getPassword())) {
            	throw new RuntimeException( "登录失败,账号或者密码不正确" );
            }
            if (ExUser.IS_ACTIVED != exUserFromDb.getStatus()) {
            	throw new RuntimeException( "该账号已不可用" );
            }
            //查询出该用户 的登录策略
            ExUserLoginStrategyEntity strategy = exUserMapper.selectByStrategy(userId);
            if (strategy == null) throw new RuntimeException("数据错误，查找不到该用户的 登录策略");
            switch (strategy.getLoginWay()) {
                case "1":      //1表示  集群中的每个机器以各自的身份登录
                    signature = CommonUtil.getUuid();
                    exUserMapper.refershToken(accountName, signature);
                    break;
                case "2":
                    break;    //2表示 集群中的每个机器实例以 同一身份登录
                default:
                    break;
            }
            //增加登录次数
            exUserMapper.addLoginCount(userId);
            return PaasResult.success("login success" , TokenUtil.encoderToken(new TokenEntity(accountName, lastLogin, signature)) );
        }

        //【先注释掉，如果有必要会打开】数据库不存在该用户，则尝试注册
        /*
        exUser.setNickName(accountName);
        if (exUserMapper.insertExUser(exUser) > 0) {   // >0表示注册用户成功
            userId = exUser.getUserId();
            // 插入该用户的 数字签名 (就是一个UUID)
            exUserMapper.insertToken(new ExUserTokenEntity(userId, ip, signature));
            // 生成该用户默认的登录策略(这里数字暂时写死了)
            exUserMapper.insertLoginStrategy(new ExUserLoginStrategyEntity(userId, "1", 30, 10, 1));
            return TokenUtil.encoderToken(new TokenEntity(accountName, lastLogin, signature));
        }
        */
        //若注册也失败了，那就抛个异常
        throw new RuntimeException( "注册程序异常，请联系开发人员" );
    }

    /*
     *  指定用户id,清除该用户的token,token存在则表示 登录状态
     * @param userId     用户id
     * @return  true表示注销成功；false表示失败
     */
    @Override
    public boolean logout(String userId) {
        return exUserMapper.refershToken(userId, "") > 0;
    }


}
